﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using RRRSRoguelike.Entities;
using RRRSRoguelike.Managers;

namespace RRRSRoguelike.Helpers
{
    public class DungeonLevel
    {
        public IList<Wall> walls;

        public List<Tile[,]> layers = new List<Tile[,]>();
              
        public Tile OpenTile;       
        public int level;

        public DungeonLevel(int level,int xMax, int yMax)
        {
            this.level = level;
            walls = new List<Wall>();

            for (int i = 0; i < Enum.GetNames(typeof(Layers)).Count(); i++)
                layers.Add(new Tile[xMax, yMax]);
            
            OpenTile = new Tile();
            
            BuildRandomDungeon();
        }

        public override string ToString()
        {
            return "Dungeon Level: " + level;
        }

        private void InitializeTiles()
        {
            for (int i = 0; i < Constants.DungeonHeight; i++)
            {
                for (int j = 0; j < Constants.DungeonWidth; j++)
                {
                    //for (int l = 0; l < Enum.GetNames(typeof(Layers)).Count(); l++)
                        layers[(int)Layers.Base][j, i] = new Floor(new Point(i, j));
                }
            } 
        }

        private void BuildRandomDungeon()
        {
            InitializeTiles();
            for (int i = 0; i < Constants.DungeonWidth; i++)
            {
                Wall top = new Wall(new Point(i, 0));
                walls.Add(top);
                Wall bottom = new Wall(new Point(i, Constants.DungeonHeight - 1));
                walls.Add(bottom);
            }

            for (int i = 0; i < Constants.DungeonHeight; i++)
            {
                Wall left = new Wall(new Point(0, i));
                walls.Add(left);
                Wall right = new Wall(new Point(Constants.DungeonWidth - 1, i));
                walls.Add(right);
            }
        }

        public bool IsOKToMove(Point p)
        {
            return ((p.X > 0 && p.X < Constants.DungeonWidth - 1) && (p.Y < Constants.DungeonHeight - 1 && p.Y > 0));
        }


        public static Point ClampToDungeon(Point p)
        {
            //includes walls
            p.X = Math.Max(Math.Min(p.X, Constants.DungeonWidth-1),0);
            p.Y = Math.Max(Math.Min(p.Y, Constants.DungeonHeight-1),0);

            return p;
        }

        internal void AddTile(Tile t, Layers layer)
        {
            layers[(int)layer][t.X, t.Y] = t;
        }

        internal Object GetTile(Point point,Layers layer)
        {
            return layers[(int)layer][point.X, point.Y];
        }

        internal Object GetTopTile(Point point) 
        {
            Tile t;

            for (int i = Enum.GetNames(typeof(Layers)).Count()-1; i >= 0; i--)
            {
                if (layers[i][point.X, point.Y] != null)
                {
                    t = layers[i][point.X, point.Y];
                    return t;
                }
            }

            return null;
        }

        internal void Clear()
        {
            for (int i = 0; i < Constants.DungeonHeight; i++)
            {
                for (int j = 0; j < Constants.DungeonWidth; j++)
                {
                    for (int l = 1; l < Enum.GetNames(typeof(Layers)).Count(); l++)
                    layers[l][j, i] = null;
                }
            } 
            InitializeTiles();
        }

        internal void AddStairwell(Stairwell stairwell, Layers layer)
        {
            layers[(int)layer][stairwell.X, stairwell.Y] = stairwell;
        }

        public void CreateRandomDungeonObjects()
        {
            DungeonManager.Instance.CreatureManager.ClearMonsters();
            DungeonManager.Instance.CreatureManager.AddRandomMonstersByLevel();

            DungeonManager.Instance.PropManager.ClearProps();
            DungeonManager.Instance.PropManager.AddProps();
        }

        public Point GetValidRandomPoint()
        {
            Point p;
            do
            {
                p = new Point(DungeonManager.Instance.DungeonBuilderRandom.Next(Constants.DungeonWidth), DungeonManager.Instance.DungeonBuilderRandom.Next(Constants.DungeonWidth));
            }
            while (!IsOKToMove(p));
            return p;
        }

            public bool IsOKToPlaceMonster(Point p)
 	        {
                //this might have a problem if an effect is hiding something.
 	            object t = GetTopTile(p);

                System.Type type = t.GetType() ;

 	            if (t is Stairwell | t is Player | t is Monster)
 	                return false;
 	 
 	            return true;
 	            
 	        } 

    }
}
